* selects a location to open in the view.
*/
-typedef enum
-{
- MODE_BROWSE,
- MODE_EMPTY,
- MODE_EMPTY_SEARCH
-} PlacesViewMode;
-
struct _GtkPlacesViewPrivate
{
GVolumeMonitor *volume_monitor;
GtkPlacesOpenFlags open_flags;
GtkPlacesOpenFlags current_open_flags;
- PlacesViewMode mode;
GFile *server_list_file;
GFileMonitor *server_list_monitor;
GtkWidget *actionbar;
GtkWidget *address_entry;
GtkWidget *connect_button;
- GtkWidget *drives_box;
- GtkWidget *drives_listbox;
- GtkWidget *network_grid;
- GtkWidget *network_listbox;
+ GtkWidget *listbox;
GtkWidget *popup_menu;
GtkWidget *recent_servers_listbox;
GtkWidget *recent_servers_popover;
g_bookmark_file_free (server_list);
}
-static void
-places_view_mode_set (GtkPlacesView *view,
- PlacesViewMode mode)
-{
- GtkPlacesViewPrivate *priv;
-
- priv = gtk_places_view_get_instance_private (view);
-
- gtk_widget_set_visible (priv->network_grid, !priv->local_only);
-
- if (priv->mode != mode)
- {
- priv->mode = mode;
-
- switch (mode)
- {
- case MODE_BROWSE:
- gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "browse");
- break;
-
- case MODE_EMPTY:
- gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "empty");
- break;
-
- case MODE_EMPTY_SEARCH:
- gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "search");
- break;
- }
- }
-}
-
static void
update_view_mode (GtkPlacesView *view)
{
GtkPlacesViewPrivate *priv;
GList *children;
GList *l;
- gboolean show_drives;
- gboolean show_networks;
+ gboolean show_listbox;
priv = gtk_places_view_get_instance_private (view);
- show_drives = FALSE;
- show_networks = FALSE;
+ show_listbox = FALSE;
/* drives */
- children = gtk_container_get_children (GTK_CONTAINER (priv->drives_listbox));
+ children = gtk_container_get_children (GTK_CONTAINER (priv->listbox));
for (l = children; l; l = l->next)
{
/* GtkListBox filter rows by changing their GtkWidget::child-visible property */
if (gtk_widget_get_child_visible (l->data))
{
- show_drives = TRUE;
+ show_listbox = TRUE;
break;
}
}
g_list_free (children);
- /* networks */
- if (!priv->local_only)
+ if (!show_listbox &&
+ priv->search_query &&
+ priv->search_query[0] != '\0')
{
- children = gtk_container_get_children (GTK_CONTAINER (priv->network_listbox));
-
- for (l = children; l; l = l->next)
- {
- /* GtkListBox filter rows by changing their GtkWidget::child-visible property */
- if (gtk_widget_get_child_visible (l->data))
- {
- show_networks = TRUE;
- break;
- }
- }
-
- g_list_free (children);
- }
-
- gtk_widget_set_visible (priv->drives_box, show_drives);
- gtk_widget_set_visible (priv->network_grid, show_networks);
-
- if (!show_drives && !show_networks)
- {
- if (priv->search_query && priv->search_query[0] != '\0')
- places_view_mode_set (view, MODE_EMPTY_SEARCH);
- else
- places_view_mode_set (view, MODE_EMPTY);
-
+ gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "empty-search");
}
else
{
- places_view_mode_set (view, MODE_BROWSE);
+ gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "browse");
}
}
gboolean is_network)
{
GtkPlacesViewPrivate *priv;
- GtkWidget *container;
- GtkWidget *list;
priv = gtk_places_view_get_instance_private (view);
- list = is_network ? priv->network_listbox : priv->drives_listbox;
- container = is_network ? priv->network_grid : priv->drives_box;
+
+ g_object_set_data (G_OBJECT (row), "is-network", GINT_TO_POINTER (is_network));
g_signal_connect_swapped (gtk_places_view_row_get_event_box (GTK_PLACES_VIEW_ROW (row)),
"button-press-event",
G_CALLBACK (on_eject_button_clicked),
row);
- gtk_container_add (GTK_CONTAINER (list), row);
-
- if (!priv->local_only || (priv->local_only && !is_network))
- {
- gtk_widget_show (container);
-
- if (priv->mode == MODE_EMPTY)
- places_view_mode_set (view, MODE_BROWSE);
- }
+ gtk_container_add (GTK_CONTAINER (priv->listbox), row);
}
static void
priv = gtk_places_view_get_instance_private (view);
/* Clear all previously added items */
- children = gtk_container_get_children (GTK_CONTAINER (priv->drives_listbox));
+ children = gtk_container_get_children (GTK_CONTAINER (priv->listbox));
g_list_free_full (children, (GDestroyNotify) gtk_widget_destroy);
- children = gtk_container_get_children (GTK_CONTAINER (priv->network_listbox));
- g_list_free_full (children, (GDestroyNotify) gtk_widget_destroy);
-
- /*
- * Hide both networks and drives lists, and only show them when
- * a row is added.
- */
- gtk_widget_hide (priv->drives_box);
- gtk_widget_hide (priv->network_grid);
-
/* Add "Computer" row */
add_computer (view);
/* load saved servers */
populate_servers (view);
- if (priv->search_query && priv->search_query[0] != '\0')
- {
- update_view_mode (view);
- }
- else if (!gtk_widget_get_visible (priv->drives_box) &&
- !gtk_widget_get_visible (priv->network_grid))
- {
- places_view_mode_set (view, MODE_EMPTY);
- }
+ update_view_mode (view);
}
static void
gpointer user_data)
{
GtkPlacesViewPrivate *priv;
+ gboolean is_network;
gboolean retval;
gchar *name;
gchar *path;
priv = gtk_places_view_get_instance_private (GTK_PLACES_VIEW (user_data));
retval = FALSE;
+ is_network = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row), "is-network"));
+
+ if (is_network && priv->local_only)
+ return FALSE;
+
if (!priv->search_query || priv->search_query[0] == '\0')
return TRUE;
return retval;
}
+static void
+listbox_header_func (GtkListBoxRow *row,
+ GtkListBoxRow *before,
+ gpointer user_data)
+{
+ gboolean row_is_network;
+ gchar *text;
+
+ text = NULL;
+ row_is_network = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row), "is-network"));
+
+ if (!before)
+ {
+ text = g_strdup_printf ("<b>%s</b>", row_is_network ? _("Networks") : _("On This Computer"));
+ }
+ else
+ {
+ gboolean before_is_network;
+
+ before_is_network = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (before), "is-network"));
+
+ if (before_is_network != row_is_network)
+ text = g_strdup_printf ("<b>%s</b>", row_is_network ? _("Networks") : _("On This Computer"));
+
+ }
+
+ if (text)
+ {
+ GtkWidget *header;
+ GtkWidget *label;
+ GtkWidget *separator;
+
+ header = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+
+ separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+
+ label = g_object_new (GTK_TYPE_LABEL,
+ "hexpand", TRUE,
+ "use_markup", TRUE,
+ "label", text,
+ "xalign", 0,
+ NULL);
+
+ g_object_set (label,
+ "margin-top", 6,
+ "margin-start", 12,
+ "margin-end", 12,
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (header), label);
+ gtk_container_add (GTK_CONTAINER (header), separator);
+ gtk_widget_show_all (header);
+
+ gtk_list_box_row_set_header (row, header);
+
+ g_free (text);
+ }
+ else
+ {
+ gtk_list_box_row_set_header (row, NULL);
+ }
+}
+
+static gint
+listbox_sort_func (GtkListBoxRow *row1,
+ GtkListBoxRow *row2,
+ gpointer user_data)
+{
+ gboolean row1_is_network;
+ gboolean row2_is_network;
+
+ row1_is_network = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row1), "is-network"));
+ row2_is_network = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row2), "is-network"));
+
+ return row1_is_network - row2_is_network;
+}
+
static void
gtk_places_view_constructed (GObject *object)
{
G_OBJECT_CLASS (gtk_places_view_parent_class)->constructed (object);
- gtk_list_box_set_filter_func (GTK_LIST_BOX (priv->drives_listbox),
+ gtk_list_box_set_sort_func (GTK_LIST_BOX (priv->listbox),
+ listbox_sort_func,
+ object,
+ NULL);
+ gtk_list_box_set_filter_func (GTK_LIST_BOX (priv->listbox),
listbox_filter_func,
object,
NULL);
- gtk_list_box_set_filter_func (GTK_LIST_BOX (priv->network_listbox),
- listbox_filter_func,
+ gtk_list_box_set_header_func (GTK_LIST_BOX (priv->listbox),
+ listbox_header_func,
object,
NULL);
gtk_widget_class_bind_template_child_private (widget_class, GtkPlacesView, address_entry_completion);
gtk_widget_class_bind_template_child_private (widget_class, GtkPlacesView, completion_store);
gtk_widget_class_bind_template_child_private (widget_class, GtkPlacesView, connect_button);
- gtk_widget_class_bind_template_child_private (widget_class, GtkPlacesView, drives_box);
- gtk_widget_class_bind_template_child_private (widget_class, GtkPlacesView, drives_listbox);
- gtk_widget_class_bind_template_child_private (widget_class, GtkPlacesView, network_grid);
- gtk_widget_class_bind_template_child_private (widget_class, GtkPlacesView, network_listbox);
+ gtk_widget_class_bind_template_child_private (widget_class, GtkPlacesView, listbox);
gtk_widget_class_bind_template_child_private (widget_class, GtkPlacesView, recent_servers_listbox);
gtk_widget_class_bind_template_child_private (widget_class, GtkPlacesView, recent_servers_popover);
gtk_widget_class_bind_template_child_private (widget_class, GtkPlacesView, recent_servers_stack);
g_clear_pointer (&priv->search_query, g_free);
priv->search_query = g_strdup (query_text);
- gtk_list_box_invalidate_filter (GTK_LIST_BOX (priv->drives_listbox));
- gtk_list_box_invalidate_filter (GTK_LIST_BOX (priv->network_listbox));
+ gtk_list_box_invalidate_filter (GTK_LIST_BOX (priv->listbox));
+ gtk_list_box_invalidate_headers (GTK_LIST_BOX (priv->listbox));
update_view_mode (view);
}
priv->local_only = local_only;
gtk_widget_set_visible (priv->actionbar, !local_only);
- gtk_widget_set_visible (priv->network_grid, !local_only);
+ gtk_list_box_invalidate_filter (GTK_LIST_BOX (priv->listbox));
update_view_mode (view);
<property name="can_focus">False</property>
<property name="shadow_type">none</property>
<child>
- <object class="GtkBox" id="main_box">
+ <object class="GtkListBox" id="listbox">
<property name="visible">True</property>
- <property name="hexpand">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkBox" id="drives_box">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="margin_start">12</property>
- <property name="margin_end">12</property>
- <property name="margin_top">6</property>
- <property name="margin_bottom">6</property>
- <property name="label" translatable="yes">This Computer</property>
- <property name="xalign">0</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkSeparator">
- <property name="visible">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkListBox" id="drives_listbox">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="selection_mode">none</property>
- <signal name="row-activated" handler="on_listbox_row_activated" object="GtkPlacesView" swapped="yes" />
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkGrid" id="network_grid">
- <property name="visible">True</property>
- <property name="hexpand">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="margin_start">12</property>
- <property name="margin_end">12</property>
- <property name="margin_top">6</property>
- <property name="margin_bottom">6</property>
- <property name="hexpand">False</property>
- <property name="label" translatable="yes" comments="Translators: header of the Network section of the Other Locations view">Network</property>
- <property name="ellipsize">end</property>
- <property name="xalign">0</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkSpinner" id="network_spinner">
- <property name="visible">True</property>
- <property name="halign">start</property>
- <property name="hexpand">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkSeparator">
- <property name="visible">True</property>
- <property name="hexpand">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
- <property name="width">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkListBox" id="network_listbox">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="selection_mode">none</property>
- <signal name="row-activated" handler="on_listbox_row_activated" object="GtkPlacesView" swapped="yes" />
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">2</property>
- <property name="width">2</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
+ <property name="can_focus">True</property>
+ <property name="selection_mode">none</property>
+ <signal name="row-activated" handler="on_listbox_row_activated" object="GtkPlacesView" swapped="yes" />
</object>
</child>
<style>
<property name="name">browse</property>
</packing>
</child>
- <child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">center</property>
- <property name="valign">center</property>
- <property name="hexpand">True</property>
- <property name="vexpand">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="pixel_size">72</property>
- <property name="icon_name">drive-harddisk-symbolic</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">No drives or networks found</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- <attribute name="scale" value="1.44"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="name">empty</property>
- <property name="position">1</property>
- </packing>
- </child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
</child>
</object>
<packing>
- <property name="name">search</property>
- <property name="position">2</property>
+ <property name="name">empty-search</property>
</packing>
</child>
</object>